﻿using Demo.Domains.Entities.Sys;
using Demo.PetaPoco.Application.Dtos.Area;
using Demo.PetaPoco.Application.Dtos.Vue;
using Microsoft.Extensions.DependencyInjection;
using PmSoft.Core;

namespace Demo.PetaPoco.Application.Services.Area;

[Inject(ServiceLifetime.Scoped)]
public class AreaService(AreaRepository _areaRepository)
{

	/// <summary>
	/// 从 Areas 解析出省市县
	/// </summary>
	/// <param name="model">包含 Areas 的模型</param>
	/// <returns>返回 (Province, City, County) 元组，可能部分为 null</returns>
	public async Task<(AreaDto? Province, AreaDto? City, AreaDto? County)> ParseAreasAsync(IAreaEditModel model)
	{
		// 检查输入
		if (model?.Areas == null || model.Areas.Length == 0)
		{
			return (null, null, null); // 空输入，返回全 null
		}

		// 获取所有区划数据
		var allAreas = await _areaRepository.GetAllAsync();
		if (allAreas == null)
			throw new PmSoftException("未找到任何行政区划数据");
		var areaDtos = allAreas.Select(area => new AreaDto
		{
			Id = area.Id,
			Name = area.Name,
			Pid = area.Pid,
			Deep = area.Deep,
			Children = new List<AreaDto>()
		}).ToDictionary(a => a.Id); // 用字典加速查找

		AreaDto? province = null;
		AreaDto? city = null;
		AreaDto? county = null;

		int provinceId, cityId, countyId;
		// 根据 Areas 长度解析
		switch (model.Areas.Length)
		{
			case 1: // 只有省
				province = int.TryParse(model.Areas[0], out provinceId) ? areaDtos.GetValueOrDefault(provinceId) : null;
				break;

			case 2: // 省市
				province = int.TryParse(model.Areas[0], out provinceId) ? areaDtos.GetValueOrDefault(provinceId) : null;
				city = int.TryParse(model.Areas[1], out cityId) ? areaDtos.GetValueOrDefault(cityId) : null;
				break;

			case 3: // 省市县
				province = int.TryParse(model.Areas[0], out provinceId) ? areaDtos.GetValueOrDefault(provinceId) : null;
				city = int.TryParse(model.Areas[1], out cityId) ? areaDtos.GetValueOrDefault(cityId) : null;
				county = int.TryParse(model.Areas[2], out countyId) ? areaDtos.GetValueOrDefault(countyId) : null;
				break;

			default: // 长度异常，返回空
				return (null, null, null);
		}

		// 验证层级关系（可选）
		if (county != null && city != null && county.Pid != city.Id)
			return (null, null, null); // 县的 Pid 不匹配市
		if (city != null && province != null && city.Pid != province.Id)
			return (null, null, null); // 市的 Pid 不匹配省

		return (province, city, county);
	}


	/// <summary>
	/// 根据父节点 ID 获取子节点，并转换为 OptionItem
	/// </summary>
	/// <param name="parentId">父节点 ID，顶级节点传入 0</param>
	/// <returns>返回子节点的 OptionItem 集合</returns>
	public async Task<IEnumerable<OptionItem>> GetChildrenAsOptionItemsAsync(int parentId)
	{
		var allAreas = await _areaRepository.GetAllAsync();
		if (allAreas == null)
			throw new PmSoftException("未找到任何行政区划数据");
		var children = allAreas.Where(a => a.Pid == parentId).Select(area => new OptionItem
		{
			Label = area.Name,
			Value = area.Id.ToString(),
			Children = null // 懒加载时不预加载子节点
		}).ToList();

		return children;
	}

	/// <summary>
	/// 获取顶级行政区划节点，并递归获取所有子节点，转换为 AreaDto
	/// </summary>
	/// <returns>返回顶级区划的 AreaDto 集合</returns>
	public async Task<IEnumerable<AreaDto>> GetTopLevelAreasWithChildrenAsync()
	{
		// 获取所有区划数据
		var allAreas = await _areaRepository.GetAllAsync();
		if (allAreas == null)
			throw new PmSoftException("未找到任何行政区划数据");
		// 将 SysArea 转换为 AreaDto，并初始化 Children
		var areaDtos = allAreas.Select(area => new AreaDto
		{
			Id = area.Id,
			Name = area.Name,
			Pid = area.Pid,
			Deep = area.Deep,
			Children = new List<AreaDto>() // 初始化为空列表
		}).ToList();

		// 查找顶级节点（Pid 为 0）
		var topLevelAreas = areaDtos.Where(a => a.Pid == 0).ToList();

		// 为每个顶级节点递归添加子节点
		foreach (var topArea in topLevelAreas)
		{
			topArea.Children = GetChildrenRecursive(topArea.Id, areaDtos);
		}

		return topLevelAreas;
	}

	/// <summary>
	/// 递归获取所有子节点
	/// </summary>
	/// <param name="parentId">父节点 ID</param>
	/// <param name="allAreas">所有区划的 AreaDto 列表</param>
	/// <returns>返回子节点的 AreaDto 集合</returns>
	private IEnumerable<AreaDto> GetChildrenRecursive(int parentId, List<AreaDto> allAreas)
	{
		// 查找当前父节点的所有直接子节点
		var children = allAreas.Where(a => a.Pid == parentId).ToList();

		// 为每个子节点递归获取其子节点
		foreach (var child in children)
		{
			child.Children = GetChildrenRecursive(child.Id, allAreas);
		}

		return children;
	}

	/// <summary>
	/// 根据任意节点 ID 获取上级省市节点，以元组形式返回
	/// </summary>
	/// <param name="id">目标节点 ID</param>
	/// <returns>返回 (Province, City) 元组，Province 为省节点，City 为市节点，可能为 null</returns>
	public async Task<(AreaDto? Province, AreaDto? City)> GetParentProvinceCityTupleAsync(int id)
	{
		// 获取所有区划数据（保持 SysArea 类型）
		var allAreas = await _areaRepository.GetAllAsync();

		// 查找目标节点
		var targetArea = allAreas?.FirstOrDefault(a => a.Id == id);
		if (targetArea == null)
		{
			return (null, null); // 目标节点不存在，返回 (null, null)
		}

		// 根据 Deep 值确定上级省市
		SysArea? provinceArea = null;
		SysArea? cityArea = null;

		switch (targetArea.Deep)
		{
			case 2: // 县节点，查找市和省
				cityArea = allAreas?.FirstOrDefault(a => a.Id == targetArea.Pid); // 上级市
				if (cityArea != null)
				{
					provinceArea = allAreas?.FirstOrDefault(a => a.Id == cityArea.Pid); // 上级省
				}
				break;
			case 1: // 市节点，查找省
				provinceArea = allAreas?.FirstOrDefault(a => a.Id == targetArea.Pid); // 上级省
				break;

			case 0: // 省节点，无上级
				break;

			default: // 其他深度（理论上不存在），返回 (null, null)
				return (null, null);
		}

		// 最后将结果转换为 AreaDto
		AreaDto? provinceDto = provinceArea != null ? new AreaDto
		{
			Id = provinceArea.Id,
			Name = provinceArea.Name,
			Pid = provinceArea.Pid,
			Deep = provinceArea.Deep,
			Children = new List<AreaDto>()
		} : null;

		AreaDto? cityDto = cityArea != null ? new AreaDto
		{
			Id = cityArea.Id,
			Name = cityArea.Name,
			Pid = cityArea.Pid,
			Deep = cityArea.Deep,
			Children = new List<AreaDto>()
		} : null;

		return (provinceDto, cityDto); // 返回元组 (Province, City)
	}
}
